/*
 * Copyright (C) 2016, apexes.net. All rights reserved.
 * 
 *        http://www.apexes.net
 * 
 */
package net.apexes.wsonrpc.client;

import net.apexes.wsonrpc.core.IdGenerator;
import net.apexes.wsonrpc.core.JsonRpcLogger;
import net.apexes.wsonrpc.core.RemoteInvoker;
import net.apexes.wsonrpc.json.JsonImplementor;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 
 * @author <a href=mailto:hedyn@foxmail.com>HeDYn</a>
 *
 */
public final class JsonRpc {
    
    public static JsonRpc url(String url) {
        return url(UrlProvider.fixedUrl(url));
    }

    public static JsonRpc url(UrlProvider urlProvider) {
        return new JsonRpc(urlProvider);
    }
    
    private final UrlProvider urlProvider;
    private final Map<String, String> headers = new LinkedHashMap<>();
    private JsonImplementor jsonImpl;
    private int connectTimeout;
    private boolean acceptCompress;
    private IdGenerator idGenerator;
    private JsonRpcLogger jsonRpcLogger;
    
    private JsonRpc(UrlProvider urlProvider) {
        this.urlProvider = urlProvider;
    }

    public JsonRpc header(String key, String value) {
        headers.put(key, value);
        return this;
    }

    public JsonRpc json(JsonImplementor jsonImpl) {
        this.jsonImpl = jsonImpl;
        return this;
    }
    
    /**
     * 设置连接超时的毫秒数
     * @param connectTimeout 连接超时的毫秒数
     * @return 返回当前实例
     */
    public JsonRpc connectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
        return this;
    }
    
    /**
     * 设置是否压缩数据
     * @param acceptCompress 为true时表示压缩数据
     * @return 返回当前实例
     */
    public JsonRpc acceptCompress(boolean acceptCompress) {
        this.acceptCompress = acceptCompress;
        return this;
    }

    /**
     * 设置请求ID生成器
     * @param idGenerator ID生成器
     * @return 返回当前实例
     */
    public JsonRpc idGenerator(IdGenerator idGenerator) {
        this.idGenerator = idGenerator;
        return this;
    }

    /**
     * 设置日志输出
     * @param logger 日志输出器
     * @return 返回当前实例
     */
    public JsonRpc logger(JsonRpcLogger logger) {
        this.jsonRpcLogger = logger;
        return this;
    }

    /**
     * 创建远程执行器
     * @return 返回创建的远程执行器
     */
    public RemoteInvoker invoker() {
        HttpJsonRpcRemote remote = new HttpJsonRpcRemote(urlProvider, jsonImpl, idGenerator);
        remote.setConnectTimeout(connectTimeout);
        remote.setAcceptCompress(acceptCompress);
        remote.setJsonRpcLogger(jsonRpcLogger);
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            remote.setHeader(entry.getKey(), entry.getValue());
        }
        return RemoteInvoker.create(remote);
    }

}
